﻿// === Copyright 2008 Jamie Macia et al. ===
// Module:      AttackEntry
// Created:     11/18/2008
// Author:      Jamie Macia
// Description: UserControl to represent an attack/damage combination in a GUI format.
// Revisions:
//      *jmacia 11/18 Issue 1: Created

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;

namespace JMacia.Gaming.d20
{
    /// <summary>
    /// GUI representation of a single attack/damage combination
    /// </summary>
    public partial class AttackEntry : UserControl
    {
        /// <summary>
        /// Default constructor
        /// </summary>
        public AttackEntry()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Simplified mapping to allow XML serialization
        /// </summary>
        public AttackDefinition Definition
        {
            get
            {
                return new AttackDefinition(this);
            }
            set
            {
                this.AttackType = value.AttackType;
                this.IncludeInRoll = value.IncludeInRoll;
                this.Attacks = value.Attacks;
                this.Damage = value.Damage;
            }
        }

        /// <summary>
        /// Should this attack/damage be included in the full attack sequence?
        /// </summary>
        public bool IncludeInRoll
        {
            get
            {
                return chkInclude.Checked;
            }
            set
            {
                chkInclude.Checked = value;
            }
        }
        
        /// <summary>
        /// A name for the attack
        /// </summary>
        public string AttackType
        {
            get
            {
                return txtAttackType.Text;
            }
            set
            {
                txtAttackType.Text = value;
            }
        }
        
        /// <summary>
        /// The full attack roll definition.
        /// </summary>
        public AttackRoll Attacks
        {
            get
            {
                return new AttackRoll((int)udHighest.Value, (int)udAtHighest.Value, (int)udIterative.Value, (int)udCrit.Value);
            }
            set
            {
                udHighest.Value = value.HighestBonus;
                udAtHighest.Value = value.AttacksAtHighest;
                udIterative.Value = value.IterativeAttacks;
                udCrit.Value = value.CriticalHitThreshold;
            }
        }

        /// <summary>
        /// The damage the attack deals
        /// </summary>
        public DamageRoll Damage
        {
            get
            {
                return new DamageRoll(txtDamageMult.Text, txtDamageStatic.Text, (int)udMultiplier.Value);
            }
            set
            {
                txtDamageMult.Text = value.ToString("M");
                txtDamageStatic.Text = value.ToString("S");
                udMultiplier.Value = value.CritMultiplier;
            }
        }

    }

    /// <summary>
    /// Simplified, non-GUI version of the AttackEntry that can be XML 
    /// serialized and has a 1-to-1 mapping onto the AttackEntry
    /// </summary>
    public class AttackDefinition
    {
        /// <summary>
        /// Empty constructor
        /// </summary>
        public AttackDefinition() { }
        /// <summary>
        /// Simplifies the AttackEntry into a serializable form
        /// </summary>
        /// <param name="basis">The AttackEntry control to be serialized</param>
        /// <exception cref="ArgumentException">Re-throws exceptions it receives from the attack and damage constructors</exception>
        public AttackDefinition(AttackEntry basis)
        {
            try
            {
                Attacks = basis.Attacks;
                Damage = basis.Damage;
            }
            catch (ArgumentException e)
            {
                throw new ArgumentException("The attack and damage could not be understood.", e);
            }
            catch (Exception e)
            {
                throw new Exception("An unknown error occurred in processing the attack and damage", e);
            }

            AttackType = basis.AttackType;
            IncludeInRoll = basis.IncludeInRoll;
        }
        /// <summary>
        /// Constructs a definition without an AttackEntry
        /// </summary>
        /// <param name="attacks">The full attack definition</param>
        /// <param name="damage">The damage dealt by this attack</param>
        /// <param name="attackType">A name for the attack</param>
        public AttackDefinition(AttackRoll attacks, DamageRoll damage, string attackType)
        {
            Attacks = attacks;
            Damage = damage;
            AttackType = attackType;
        }
        /// <summary>
        /// The full attack definition
        /// </summary>
        public AttackRoll Attacks { get; set; }
        /// <summary>
        /// The damage dealt by this attack
        /// </summary>
        public DamageRoll Damage { get; set; }
        /// <summary>
        /// The name of this attack
        /// </summary>
        public string AttackType { get; set; }
        /// <summary>
        /// Whether or not this attack should be included in the greater full attack sequence
        /// </summary>
        public bool IncludeInRoll { get; set; }
        
    }
}
